home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / Services / Weather / Ejse.php < prev    next >
Encoding:
PHP Script  |  2004-10-01  |  14.6 KB  |  394 lines

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2004 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.0 of the PHP license,       |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available through the world-wide-web at                              |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Alexander Wirtz <alex@pc4p.net>                             |
  17. // +----------------------------------------------------------------------+
  18. //
  19. // $Id: Ejse.php,v 1.14 2004/05/01 12:49:26 eru Exp $
  20.  
  21. /**
  22. * @package      Services_Weather
  23. * @filesource
  24. */
  25.  
  26. /**
  27. */
  28. require_once "Services/Weather/Common.php";
  29.  
  30. // {{{ class Services_Weather_Ejse
  31. /**
  32. * PEAR::Services_Weather_Ejse
  33. *
  34. * This class acts as an interface to the soap service of EJSE. It retrieves
  35. * current weather data and forecasts based on postal codes (ZIP).
  36. *
  37. * Currently this service is only available for US territory.
  38. *
  39. * For a working example, please take a look at
  40. *     docs/Services_Weather/examples/ejse-basic.php
  41. *
  42. * @author       Alexander Wirtz <alex@pc4p.net>
  43. * @link         http://www.ejse.com/services/weather_xml_web_services.htm
  44. * @example      examples/ejse-basic.php ejse-basic.php
  45. * @package      Services_Weather
  46. * @license      http://www.php.net/license/2_02.txt
  47. * @version      1.3
  48. */
  49. class Services_Weather_Ejse extends Services_Weather_Common {
  50.  
  51.     // {{{ properties
  52.     /**
  53.     * WSDL object, provided by EJSE
  54.     *
  55.     * @var      object                      $_wsdl
  56.     * @access   private
  57.     */
  58.     var $_wsdl;
  59.  
  60.     /**
  61.     * SOAP object to access weather data, provided by EJSE
  62.     *
  63.     * @var      object                      $_weaterSoap
  64.     * @access   private
  65.     */
  66.     var $_weatherSoap;
  67.     // }}}
  68.  
  69.     // {{{ constructor
  70.     /**
  71.     * Constructor
  72.     *
  73.     * Requires SOAP to be installed
  74.     *
  75.     * @param    array                       $options
  76.     * @param    mixed                       $error
  77.     * @throws   PEAR_Error
  78.     * @throws   PEAR_Error::SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA
  79.     * @see      Science_Weather::Science_Weather
  80.     * @access   private
  81.     */
  82.     function Services_Weather_Ejse($options, &$error)
  83.     {
  84.         $perror = null;
  85.         $this->Services_Weather_Common($options, $perror);
  86.         if (Services_Weather::isError($perror)) {
  87.             $error = $perror;
  88.             return;
  89.         }
  90.  
  91.         include_once "SOAP/Client.php";
  92.         $this->_wsdl = new SOAP_WSDL("http://www.ejse.com/WeatherService/Service.asmx?WSDL", array("timeout" => $this->_httpTimeout));
  93.         if (isset($this->_wsdl->fault) && Services_Weather::isError($this->_wsdl->fault)) {
  94.             $error = Services_Weather::raiseError(SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA, __FILE__, __LINE__);
  95.             return;
  96.         }
  97.  
  98.         eval($this->_wsdl->generateAllProxies());
  99.         if (!class_exists("WebService_Service_ServiceSoap")) {
  100.             $error = Services_Weather::raiseError(SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA, __FILE__, __LINE__);
  101.             return;
  102.         }
  103.  
  104.         $this->_weatherSoap = &new WebService_Service_ServiceSoap;
  105.     }
  106.     // }}}
  107.  
  108.     // {{{ _checkLocationID()
  109.     /**
  110.     * Checks the id for valid values and thus prevents silly requests to EJSE server
  111.     *
  112.     * @param    string                      $id
  113.     * @return   PEAR_Error|bool
  114.     * @throws   PEAR_Error::SERVICES_WEATHER_ERROR_NO_LOCATION
  115.     * @throws   PEAR_Error::SERVICES_WEATHER_ERROR_INVALID_LOCATION
  116.     * @access   private
  117.     */
  118.     function _checkLocationID($id)
  119.     {
  120.         if (is_array($id) || is_object($id) || !strlen($id)) {
  121.             return Services_Weather::raiseError(SERVICES_WEATHER_ERROR_NO_LOCATION, __FILE__, __LINE__);
  122.         } elseif (!ctype_digit($id) || (strlen($id) != 5)) {
  123.             return Services_Weather::raiseError(SERVICES_WEATHER_ERROR_INVALID_LOCATION, __FILE__, __LINE__);
  124.         }
  125.  
  126.         return true;
  127.     }
  128.     // }}}
  129.  
  130.     // {{{ searchLocation()
  131.     /**
  132.     * EJSE offers no search function to date, so this function is disabled.
  133.     * Maybe this is the place to interface to some online postcode service... 
  134.     *
  135.     * @param    string                      $location
  136.     * @param    bool                        $useFirst
  137.     * @return   bool
  138.     * @access   public
  139.     * @deprecated
  140.     */
  141.     function searchLocation($location = null, $useFirst = null)
  142.     {
  143.         return $false;
  144.     }
  145.     // }}}
  146.  
  147.     // {{{ searchLocationByCountry()
  148.     /**
  149.     * EJSE offers no search function to date, so this function is disabled.
  150.     * Maybe this is the place to interface to some online postcode service... 
  151.     *
  152.     * @param    string                      $country
  153.     * @return   bool
  154.     * @access   public
  155.     * @deprecated
  156.     */
  157.     function searchLocationByCountry($country = null)
  158.     {
  159.         return $false;
  160.     }
  161.     // }}}
  162.  
  163.     // {{{ getLocation()
  164.     /**
  165.     * Returns the data for the location belonging to the ID
  166.     *
  167.     * @param    string                      $id
  168.     * @return   PEAR_Error|array
  169.     * @throws   PEAR_Error
  170.     * @access   public
  171.     */
  172.     function getLocation($id = "")
  173.     {
  174.         $status = $this->_checkLocationID($id);
  175.  
  176.         if (Services_Weather::isError($status)) {
  177.             return $status;
  178.         }
  179.  
  180.         $locationReturn = array();
  181.  
  182.         if ($this->_cacheEnabled && ($weather = $this->_cache->get($id, "weather"))) {
  183.             // Get data from cache
  184.             $this->_weather = $weather;
  185.             $locationReturn["cache"] = "HIT";
  186.         } else {
  187.             $weather = $this->_weatherSoap->getWeatherInfo($id);
  188.  
  189.             if (Services_Weather::isError($weather)) {
  190.                 return $weather;
  191.             }
  192.  
  193.             $this->_weather = $weather;
  194.  
  195.             if ($this->_cacheEnabled) {
  196.                 // ...and cache it
  197.                 $expire = constant("SERVICES_WEATHER_EXPIRES_WEATHER");
  198.                 $this->_cache->extSave($id, $this->_weather, "", $expire, "weather");
  199.             }
  200.             $locationReturn["cache"] = "MISS";
  201.         }
  202.         $locationReturn["name"] = $this->_weather->Location;
  203.  
  204.         return $locationReturn;
  205.     }
  206.     // }}}
  207.  
  208.     // {{{ getWeather()
  209.     /**
  210.     * Returns the weather-data for the supplied location
  211.     *
  212.     * @param    string                      $id
  213.     * @param    string                      $unitsFormat
  214.     * @return   PEAR_Error|array
  215.     * @throws   PEAR_Error
  216.     * @access   public
  217.     */
  218.     function getWeather($id = "", $unitsFormat = "")
  219.     {
  220.         $status = $this->_checkLocationID($id);
  221.  
  222.         if (Services_Weather::isError($status)) {
  223.             return $status;
  224.         }
  225.  
  226.         // Get other data
  227.         $units    = $this->getUnitsFormat($unitsFormat);
  228.  
  229.         $weatherReturn = array();
  230.         if ($this->_cacheEnabled && ($weather = $this->_cache->get($id, "weather"))) {
  231.             // Same procedure...
  232.             $this->_weather = $weather;
  233.             $weatherReturn["cache"] = "HIT";
  234.         } else {
  235.             // ...as last function
  236.             $weather = $this->_weatherSoap->getWeatherInfo($id);
  237.  
  238.             if (Services_Weather::isError($weather)) {
  239.                 return $weather;
  240.             }
  241.  
  242.             $this->_weather = $weather;
  243.  
  244.             if ($this->_cacheEnabled) {
  245.                 // ...and cache it
  246.                 $expire = constant("SERVICES_WEATHER_EXPIRES_WEATHER");
  247.                 $this->_cache->extSave($id, $this->_weather, "", $expire, "weather");
  248.             }
  249.             $weatherReturn["cache"] = "MISS";
  250.         }
  251.  
  252.         if (!isset($compass)) {
  253.             // Yes, NNE and the likes are multiples of 22.5, but as the other
  254.             // services return integers for this value, these directions are
  255.             // rounded up
  256.             $compass = array(
  257.                 "north"             => array("N",     0),
  258.                 "north northeast"   => array("NNE",  23),
  259.                 "northeast"         => array("NE",   45),
  260.                 "east northeast"    => array("ENE",  68),
  261.                 "east"              => array("E",    90),
  262.                 "east southeast"    => array("ESE", 113),
  263.                 "southeast"         => array("SE",  135),
  264.                 "south southeast"   => array("SSE", 158),
  265.                 "south"             => array("S",   180),
  266.                 "south southwest"   => array("SSW", 203),
  267.                 "southwest"         => array("SW",  225),
  268.                 "west southwest"    => array("WSW", 248),
  269.                 "west"              => array("W",   270),
  270.                 "west northwest"    => array("WNW", 293),
  271.                 "northwest"         => array("NW",  315),
  272.                 "north northwest"   => array("NNW", 338)
  273.             );
  274.         }
  275.  
  276.         preg_match("/(\w+) (\d+), (\d+), at (\d+:\d+ \wM) [^\(]+(\(([^\)]+)\))?/", $this->_weather->LastUpdated, $update);
  277.         if (isset($update[5])) {
  278.             $timestring = $update[6];
  279.         } else {
  280.             $timestring = $update[2]." ".$update[1]." ".$update[3]." ".$update[4]." EST";
  281.         }
  282.         $weatherReturn["update"]            = gmdate(trim($this->_dateFormat." ".$this->_timeFormat), strtotime($timestring));
  283.         $weatherReturn["updateRaw"]            = $this->_weather->LastUpdated;
  284.         $weatherReturn["station"]           = $this->_weather->ReportedAt;
  285.         $weatherReturn["conditionIcon"]     = $this->_weather->IconIndex;
  286.         preg_match("/(-?\d+)\D+/", $this->_weather->Temprature, $temperature);        
  287.         $weatherReturn["temperature"]       = $this->convertTemperature($temperature[1], "f", $units["temp"]);
  288.         preg_match("/(-?\d+)\D+/", $this->_weather->FeelsLike, $feltTemperature);        
  289.         $weatherReturn["feltTemperature"]   = $this->convertTemperature($feltTemperature[1], "f", $units["temp"]);
  290.         $weatherReturn["condition"]         = $this->_weather->Forecast;
  291.         if (preg_match("/([\d\.]+)\D+/", $this->_weather->Visibility, $visibility)) { 
  292.             $weatherReturn["visibility"]    = $this->convertDistance($visibility[1], "sm", $units["vis"]);
  293.         } else {
  294.             $weatherReturn["visibility"]    = trim($this->_weather->Visibility);
  295.         } 
  296.         preg_match("/([\d\.]+) inches and (\w+)/", $this->_weather->Pressure, $pressure);
  297.         $weatherReturn["pressure"]          = $this->convertPressure($pressure[1], "in", $units["pres"]);        
  298.         $weatherReturn["pressureTrend"]     = $pressure[2];
  299.         preg_match("/(-?\d+)\D+/", $this->_weather->DewPoint, $dewPoint);      
  300.         $weatherReturn["dewPoint"]          = $this->convertTemperature($dewPoint[1], "f", $units["temp"]);
  301.         preg_match("/(\d+) (\w+)/", $this->_weather->UVIndex, $uvIndex);
  302.         $weatherReturn["uvIndex"]           = $uvIndex[1];
  303.         $weatherReturn["uvText"]            = $uvIndex[2];
  304.         $weatherReturn["humidity"]          = str_replace("%", "", $this->_weather->Humidity);
  305.         if (preg_match("/From the ([\w\ ]+) at ([\d\.]+) (gusting to ([\d\.]+) )?mph/", $this->_weather->Wind, $wind)) {
  306.             $weatherReturn["wind"]              = $this->convertSpeed($wind[2], "mph", $units["wind"]);
  307.             if (isset($wind[4])) {
  308.                 $weatherReturn["windGust"]      = $this->convertSpeed($wind[4], "mph", $units["wind"]);
  309.             }
  310.             $weatherReturn["windDegrees"]       = $compass[strtolower($wind[1])][1];
  311.             $weatherReturn["windDirection"]     = $compass[strtolower($wind[1])][0];
  312.         } elseif (strtolower($this->_weather->Wind) == "calm") {
  313.             $weatherReturn["wind"]          = 0;
  314.             $weatherReturn["windDegrees"]   = 0;
  315.             $weatherReturn["windDirection"] = "CALM";
  316.         }
  317.  
  318.         return $weatherReturn;
  319.     }
  320.     // }}}
  321.  
  322.     // {{{ getForecast()
  323.     /**
  324.     * Get the forecast for the next days
  325.     *
  326.     * @param    string                      $int
  327.     * @param    int                         $days           Values between 1 and 9
  328.     * @param    string                      $unitsFormat
  329.     * @return   PEAR_Error|array
  330.     * @throws   PEAR_Error
  331.     * @access   public
  332.     */
  333.     function getForecast($id = "", $days = 2, $unitsFormat = "")
  334.     {
  335.         $status = $this->_checkLocationID($id);
  336.  
  337.         if (Services_Weather::isError($status)) {
  338.             return $status;
  339.         }
  340.         if (!in_array($days, range(1, 9))) {
  341.             $days = 2;
  342.         }
  343.  
  344.         // Get other data
  345.         $units    = $this->getUnitsFormat($unitsFormat);
  346.  
  347.         $forecastReturn = array();
  348.         if ($this->_cacheEnabled && ($forecast = $this->_cache->get($id, "forecast"))) {
  349.             // Same procedure...
  350.             $this->_forecast = $forecast;
  351.             $forecastReturn["cache"] = "HIT";
  352.         } else {
  353.             // ...as last function
  354.             $forecast = $this->_weatherSoap->GetNineDayForecastInfo($id);
  355.  
  356.             if (Services_Weather::isError($forecast)) {
  357.                 return $forecast;
  358.             }
  359.  
  360.             $this->_forecast = $forecast;
  361.  
  362.             if ($this->_cacheEnabled) {
  363.                 // ...and cache it
  364.                 $expire = constant("SERVICES_WEATHER_EXPIRES_FORECAST");
  365.                 $this->_cache->extSave($id, $this->_forecast, "", $expire, "forecast");
  366.             }
  367.             $forecastReturn["cache"] = "MISS";
  368.         }
  369.  
  370.         $forecastReturn["days"]   = array();
  371.  
  372.         for ($i = 1; $i <= $days; $i++) {
  373.             preg_match("/(-?\d+)\D+/", $this->_forecast->{"Day".$i}->High, $temperatureHigh);        
  374.             preg_match("/(-?\d+)\D+/", $this->_forecast->{"Day".$i}->Low, $temperatureLow);        
  375.             $day = array(
  376.                 "tempertureHigh" => $this->convertTemperature($temperatureHigh[1], "f", $units["temp"]),
  377.                 "temperatureLow" => $this->convertTemperature($temperatureLow[1], "f", $units["temp"]),
  378.                 "day" => array(
  379.                     "condition"     => $this->_forecast->{"Day".$i}->Forecast,
  380.                     "conditionIcon" => $this->_forecast->{"Day".$i}->IconIndex,
  381.                     "precipitation" => trim(str_replace("%", "", $this->_forecast->{"Day".$i}->PrecipChance))
  382.                 )
  383.             );
  384.  
  385.             $forecastReturn["days"][] = $day;
  386.         }
  387.  
  388.         return $forecastReturn;        
  389.     }
  390.     // }}}
  391. }
  392. // }}}
  393. ?>
  394.